package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.constant.RedisConstant;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.web.admin.mapper.ApartmentInfoMapper;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentDetailVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentItemVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentQueryVo;
import com.atguigu.lease.web.admin.vo.apartment.ApartmentSubmitVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Optional;

/**
 * @author xiongkunYang
 * @description 针对表【apartment_info(公寓信息表)】的数据库操作Service实现
 * @createDate 2025-04-19 22:27:34
 */
@Service
@RequiredArgsConstructor
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo>
        implements ApartmentInfoService {

    private final ApartmentInfoMapper apartmentInfoMapper;
    private final ProvinceInfoService provinceInfoService;
    private final CityInfoService cityInfoService;
    private final DistrictInfoService districtInfoService;
    private final ApartmentFacilityService apartmentFacilityService;
    private final ApartmentLabelService apartmentLabelService;
    private final ApartmentFeeValueService apartmentFeeValueService;
    private final GraphInfoService graphInfoService;
    private final RedisTemplate<String, Object> redisTemplate;

    /**
     * 保存或更新公寓提交信息
     * 该方法主要用于处理公寓信息的保存或更新操作它不仅保存或更新公寓基本信息，
     * 还处理与公寓相关的设施、标签、费用值和图形信息
     *
     * @param apartmentSubmitVo 公寓提交信息对象，包含需要保存或更新的公寓信息
     * @return 返回保存或更新操作是否成功
     */
    @Override
    public Boolean saveOrUpdateSubmitVo(ApartmentSubmitVo apartmentSubmitVo) {
        // 获取公寓ID
        Long apartmentId = apartmentSubmitVo.getId();

        // 设置省份名称
        apartmentSubmitVo.setProvinceName(
                        Optional.ofNullable(this.provinceInfoService.getById(apartmentSubmitVo.getProvinceId()))
                                .map(ProvinceInfo::getName)
                                .orElse(null)
                ) // 设置城市名称
                .setCityName(
                        Optional.ofNullable(this.cityInfoService.getById(apartmentSubmitVo.getCityId()))
                                .map(CityInfo::getName)
                                .orElse(null)
                ) // 设置地区名称
                .setDistrictName(
                        Optional.ofNullable(this.districtInfoService.getById(apartmentSubmitVo.getDistrictId()))
                                .map(DistrictInfo::getName)
                                .orElse(null)
                );

        // 执行公寓信息的保存或更新操作
        boolean isSaveOrUpdate = super.saveOrUpdate(apartmentSubmitVo);

        // 如果是更新操作，删除与该公寓相关的旧数据
        if (apartmentId != null) {
            this.removeApartmentRelatedData(apartmentId);
        }

        // 处理公寓设施信息的保存
        Optional.ofNullable(apartmentSubmitVo.getFacilityInfoIds())
                .filter(facilityInfoIds -> !facilityInfoIds.isEmpty())
                .map(facilityInfoIds -> facilityInfoIds.stream()
                        .map(facilityId -> ApartmentFacility.builder()
                                .apartmentId(apartmentSubmitVo.getId())
                                .facilityId(facilityId)
                                .build())
                        .toList())
                .ifPresent(this.apartmentFacilityService::saveBatch);

        // 处理公寓标签信息的保存
        Optional.ofNullable(apartmentSubmitVo.getLabelIds())
                .filter(labelIds -> !labelIds.isEmpty())
                .map(labelIds -> labelIds.stream()
                        .map(labelId -> ApartmentLabel.builder()
                                .apartmentId(apartmentSubmitVo.getId())
                                .labelId(labelId)
                                .build())
                        .toList())
                .ifPresent(this.apartmentLabelService::saveBatch);

        // 处理公寓费用值信息的保存
        Optional.ofNullable(apartmentSubmitVo.getFeeValueIds())
                .filter(feeValueIds -> !feeValueIds.isEmpty())
                .map(feeValueIds -> feeValueIds.stream()
                        .map(feeValueId -> ApartmentFeeValue.builder()
                                .apartmentId(apartmentSubmitVo.getId())
                                .feeValueId(feeValueId)
                                .build())
                        .toList())
                .ifPresent(this.apartmentFeeValueService::saveBatch);

        // 处理公寓图形信息的保存
        Optional.ofNullable(apartmentSubmitVo.getGraphVoList())
                .filter(graphVoList -> !graphVoList.isEmpty())
                .map(graphVoList -> graphVoList.stream()
                        .map(graphVo -> GraphInfo.builder()
                                .itemType(ItemType.APARTMENT)
                                .itemId(apartmentSubmitVo.getId())
                                .name(graphVo.getName())
                                .url(graphVo.getUrl())
                                .build())
                        .toList())
                .ifPresent(this.graphInfoService::saveBatch);

        // 返回保存或更新操作的结果
        return isSaveOrUpdate;
    }

    @Override
    public IPage<ApartmentItemVo> apartmentItemPageByQuery(long current, long size, ApartmentQueryVo queryVo) {
        Page<ApartmentItemVo> page = new Page<>(current, size);
        return this.apartmentInfoMapper.selectApartmentItemPageByQuery(page, queryVo);
    }

    @Override
    public ApartmentDetailVo getApartmentDetailById(Long id) {
        return this.apartmentInfoMapper.selectApartmentDetailById(id);
    }

    @Override
    public Boolean removeSubmitVoById(Long id) {
        this.removeApartmentRelatedData(id);
        return super.removeById(id);
    }

    /**
     * 删除与公寓相关的所有关联数据。
     *
     * @param apartmentId 公寓ID
     */
    private void removeApartmentRelatedData(Long apartmentId) {
        this.apartmentFacilityService.remove(
                new LambdaQueryWrapper<ApartmentFacility>()
                        .eq(ApartmentFacility::getApartmentId, apartmentId));

        this.apartmentLabelService.remove(
                new LambdaQueryWrapper<ApartmentLabel>()
                        .eq(ApartmentLabel::getApartmentId, apartmentId));

        this.apartmentFeeValueService.remove(
                new LambdaQueryWrapper<ApartmentFeeValue>()
                        .eq(ApartmentFeeValue::getApartmentId, apartmentId));

        this.graphInfoService.remove(
                new LambdaQueryWrapper<GraphInfo>()
                        .eq(GraphInfo::getItemType, ItemType.APARTMENT)
                        .eq(GraphInfo::getItemId, apartmentId));
        // 删除Redis缓存
        this.redisTemplate.delete(RedisConstant.APP_APARTMENT_PREFIX + apartmentId);
    }

}




